#ifndef RENDER_H
#define RENDER_H

#include <QGLViewer/qglviewer.h>
#include "PhysicsWorld.h"
#include "Texture.h"
#include "IKSolver.h"
#include <QMouseEvent>
#include <QKeyEvent>
#include <QDebug>
#include <QDir>
#include "Macro.h"
#include "Trajectory.h"
#include "Model.h"

class CameraPathPlayer : public qglviewer::MouseGrabber
{
public:
	CameraPathPlayer(int nb) : pathNb(nb) {};
	void checkIfGrabsMouse(int x, int y, const qglviewer::Camera* const camera);
	int yPos() { return 25*pathNb; };

protected:
	void mousePressEvent(QMouseEvent* const, qglviewer::Camera* const camera) { camera->playPath(pathNb); };
private:
	int pathNb;
};


class MyManipulatedFrame : public qglviewer::ManipulatedFrame
{
public:
	void SetPhysicsWorld(PhysicsWorld* pw, dGeomID geomID)
	{
		this->pw = pw;
		this->geomID = geomID;
	}
	bool isPress()
	{
		return isPressed;
	}
	bool isRelease()
	{
		return isReleased;
	}
	void resetMouseState()
	{
		isPressed = false;
		isReleased = false;
	}
	void mySetGrabsMouse(bool myGrabsMouse)
	{
		setGrabsMouse(myGrabsMouse);
	}
	enum SelectionMode {NONE, SELECT};
	SelectionMode selectionMode;
private:
	bool isPressed;
	bool isReleased;
	PhysicsWorld* pw;
	dGeomID geomID;
protected:
	virtual void mousePressEvent(QMouseEvent* const event, qglviewer::Camera* const camera)
	{
		qglviewer::ManipulatedFrame::mousePressEvent(event, camera);
		
		isPressed = true;
		isReleased = false;

		if (event->modifiers() == Qt::ControlModifier && event->button() == Qt::LeftButton)
		{
			if (selectionMode == NONE)
				selectionMode = SELECT;
			else
				selectionMode = NONE;
		}
	};
	virtual void mouseReleaseEvent(QMouseEvent* const event, qglviewer::Camera* const camera)
	{
		qglviewer::ManipulatedFrame::mouseReleaseEvent(event, camera);
		isPressed = false;
		isReleased = true;
	};
	virtual void mouseDoubleClickEvent(QMouseEvent* const event, qglviewer::Camera* const camera)
	{
		isPressed = false;
		qglviewer::ManipulatedFrame::mouseDoubleClickEvent(event, camera);
	};
	virtual void wheelEvent(QWheelEvent* const event, qglviewer::Camera* const camera)
	{
		qglviewer::ManipulatedFrame::wheelEvent(event, camera);
		//pw->animatePhysics();
	};
};

class PhyBody
{
public:
	void draw(const float color[4]);
	const dReal* pos;
	const dReal* rot;
	MyManipulatedFrame mf;
	dBodyID bodyID;
	dGeomID geomID;
private:
	void drawSphere(float radius, const float color[4]);
	void drawCylinder(float l, float r, float zoffset, const float color[4]);
	void drawCapsule(float l, float r, const float color[4]);
	void drawBox (const float sides[3], const float color[4]);
	void setupDrawingMode(const float color[4]);
	void setColor (float r, float g, float b, float alpha);
};

class Render:public QGLViewer
{
public:
	Render(PhysicsWorld* pw, IKSolver* ccd, Model* model):QGLViewer()
	{
		//dAllocateODEDataForThread(dAllocateMaskAll);
		this->pw = pw;
		this->ccd = ccd;
		this->model = model;
	}
	~Render()
	{		
		delete[] texture;
	}
	void reset();
	void setTrajectory(Trajectory* traj){this->traj = traj;};

protected:
	virtual void init();
	virtual void draw();
	virtual QString helpString() const;
	//virtual void paintGL() { update(); };
	virtual void paintEvent(QPaintEvent *event);

	void displayPlayers();
	void updatePlayers();
	void drawGround();
	void drawJoint(float color[4], double radius, dReal* pos);
	void setTextures();
	void checkReplay();
	void drawConForce();
	void drawState();

private:
	CameraPathPlayer** player_;
	int nbPlayers_;
	QList<PhyBody> phyBodies;
	PhysicsWorld* pw;
	qglviewer::ManipulatedFrame* light1;
	qglviewer::ManipulatedFrame* light2;
	Texture *sky_texture;
	Texture *ground_texture;
	Texture *wood_texture;
	Texture *checkered_texture;
	Texture *texture[4+1];
	IKSolver* ccd;
	Trajectory* traj;
	Model* model;
};

#endif